import com.sun.org.apache.bcel.internal.generic.NEW;
import com.sun.org.apache.regexp.internal.RE;
import produce.bean.util.BeanFactory;
import produce.service.impl.HelloServiceImpl;

import java.io.*;
import java.lang.reflect.Method;
import java.net.InetSocketAddress;
import java.net.ServerSocket;
import java.net.Socket;

/**
 * @author cxx
 * @create 2020-03-17 14:59
 **/
public class RpcService {

    private static int port=9090;


    public static void main(String[] args)throws Exception {

        HelloServiceImpl helloService = new HelloServiceImpl ();
        BeanFactory.addBean ("hello",helloService);


        ServerSocket serverSocket = new ServerSocket ();

        serverSocket.bind (new InetSocketAddress (port));

        while (true){
            Socket socket = serverSocket.accept ();
            InputStream inputStream = socket.getInputStream ();
            ObjectInputStream ois = new ObjectInputStream (inputStream);
            Object requestObject = ois.readObject ();
            if(requestObject instanceof RequestObject){
                String beanName = ((RequestObject) requestObject).getTarget ();
                Object obj = BeanFactory.getBean(beanName);
                String methodName = ((RequestObject) requestObject).getMethod ();
                Object[] argArr = ((RequestObject) requestObject).getArgs ();
                Class<?> aClass = obj.getClass ();
                Method method = null;
                if(argArr != null){
                    Class[] paramType =  new Class[argArr.length];
                    for (int i = 0; i < argArr.length; i++) {
                        paramType[i] = argArr[i].getClass ();
                    }
                     method = aClass.getMethod (methodName, paramType);
                }else{
                    method = aClass.getMethod (methodName);
                }
                Object result = method.invoke (obj, argArr);
                ResponseObject responseObject = new ResponseObject ();
                responseObject.setClz (result.getClass ());
                responseObject.setTarget (result);
                ObjectOutputStream ops = new ObjectOutputStream (socket.getOutputStream ());
                ops.writeObject (responseObject);
            }
        }

    }

}
